package com.mairuide.bill.billstatus;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.mairuide._frame.base.BaseController;
import com.mairuide._frame.base.ModuleCode;
import com.mairuide._frame.base.PageSupport;
import com.mairuide.bill.DealFlow;
import com.mairuide.bill.DealFlowService;
import com.mairuide.bill.DealFlowVo;
import com.mairuide.bill.dto.DealFlowDto;
import com.mairuide.bill.methodsanalysis.CommonStatistics;
import com.mairuide.bill.treeview.BillTreeService;
import com.mairuide.bill.utils.ExcelUtil;
import com.mairuide.casemanage.pojo.CaseManage;
import com.mairuide.casemanage.service.CaseManageService;
import com.mairuide.datalog.ActionType;
import com.mairuide.datalog.DataOperationImportLog;
import com.mairuide.datalog.DataOperationImportLogService;
import com.mairuide.datalog.DataOperationLogService;
import com.mairuide.datalog.ModuleFlag;
import com.mairuide.datalog.SystemFlag;
import com.mairuide.menuinfo.MenuInfo;

/**
 * 账单概况
 * @author songRT
 */
@Controller
@RequestMapping("/bill/tj")
public class BillStatusController extends BaseController {
	@Resource
	private DealFlowService dealFlowService;
    @Resource
    private DataOperationLogService dataOperationLogService;
    @Resource
	private CaseManageService caseManageService;
    @Resource
    private DataOperationImportLogService dataOperationImportLogService;
    @Resource
	private BillTreeService billTreeService;
    
	@SuppressWarnings("unchecked")
	@ModuleCode(pValue = "bill", value = "billstatus")
	@RequestMapping(value = "/status", method = RequestMethod.GET)
	public Object billstatus(ModelMap model, PageSupport pagesupport) {
        Map<String, List<MenuInfo>> secondLevelMenuMap = (Map<String, List<MenuInfo>>)request.getSession().getAttribute("secondLevelMenuMap");
        List<MenuInfo> firstLevelMenuList = (List<MenuInfo>)request.getSession().getAttribute("firstLevelMenuList");
        for(MenuInfo m : firstLevelMenuList){
            if("账单系统".equals(m.getMenuName())){
                List<MenuInfo> menuInfos = secondLevelMenuMap.get(String.valueOf(m.getMenuId()));
                if(menuInfos!=null&&menuInfos.size()>0){
                    String menuUrl = menuInfos.get(0).getMenuUrl();
                       if(menuUrl!=null&&!"/bill/tj/status".equals(menuUrl)){
                        return "redirect:"+menuUrl;
                    }
                }
            }
        }
        /** 查询案件名称、导入电子账单个数、数据量、交易主题人数、总金额、流入金额、流出金额、 **/
        String caseManagerId = request.getSession().getAttribute("caseId") == null?"":request.getSession().getAttribute("caseId").toString();
        CaseManage caseManage = caseManageService.findByCaseUuid(caseManagerId);//查询案件名称
        /**查 询 该案件导入文件个数数据量等日志信息**/
        List<DataOperationImportLog> dataOperationImprotLogs =  dataOperationImportLogService.findByDealFlowUuid(caseManagerId);
        int sumImportNumber = 0;//导入成功流水条数
        int fileNumber = 0;//导入文件个数
        if(dataOperationImprotLogs != null && dataOperationImprotLogs.size() > 0) {
        	for(DataOperationImportLog d :dataOperationImprotLogs) {
        		sumImportNumber += d.getSuccessNumber();
        	}
        	fileNumber = dataOperationImprotLogs.size();
        }
        if(caseManage == null ) {
        	model.addAttribute("caseName", "");//案件名称
        }else {
        	model.addAttribute("caseName", caseManage.getCase_name());//案件名称
        }
        model.addAttribute("fileNumber", fileNumber);//案件下导入文件数
        model.addAttribute("sumImportNumber", sumImportNumber);//案件下导入记录数
        model.addAttribute("menu", "billstatus");
		return "/bill/billStatus";
	}
	
	/**
	 * 查询交易主体个数
	 * @return 
	 */
	@ResponseBody
	@RequestMapping(value = "/getAccountNumber", method = RequestMethod.POST)
	public Object getAccountNumber() {
		String caseManagerId = request.getSession().getAttribute("caseId") == null?"":request.getSession().getAttribute("caseId").toString();
		 /** 查询交易主体个数 **/
		int accountBodyNumber = 0;//交易主体个数个数
        Map<String,Object> btns = billTreeService.getAccountNumberByCaseManageId(caseManagerId);
        if(null != btns) {
        	accountBodyNumber = Integer.parseInt(btns.get("ACCOUNTBYDONUM").toString());
        }
		return accountBodyNumber;
	}
	
	/**
	 * 根据案件id查询账单涉嫌总金额、流入金额、流出金额 
	 * @return 
	 */
	@ResponseBody
	@RequestMapping(value = "/getTotalMoney", method = RequestMethod.POST)
	public Object getTotalMoney() {
		String caseManagerId = request.getSession().getAttribute("caseId") == null?"":request.getSession().getAttribute("caseId").toString();
		/** 根据案件id查询账单涉嫌总金额、流入金额、流出金额 **/
        Map<String, Object> billMap = dealFlowService.findBillSummary(caseManagerId);
		return billMap;
	}
	
	/**
	 * 根据案件id查询共同交易人
	 * @return 
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/getCommonAccountEC", method = RequestMethod.POST)
	@ResponseBody
	public Object getCommonAccountEC() {
		/**  根据案件id查询共同交易人 **/
		String caseManagerId = request.getSession().getAttribute("caseId") == null?"":request.getSession().getAttribute("caseId").toString();
		Map<String, Object> result = new HashMap<String, Object>();
        List<CommonStatistics> commonAccounts = dealFlowService.findCommonAccountByCaseManagerId(caseManagerId);
        if(commonAccounts != null && commonAccounts.size() > 0) {
        	if (commonAccounts.size() > 10) {
				Collections.sort(commonAccounts, new SortList());
				List<CommonStatistics> rows = commonAccounts.subList(0, 10);
				result.put("rows", rows);//共同交易人
			}else {
				result.put("rows", commonAccounts);//共同交易人
	        }
        }else {
        	result.put("rows", new ArrayList<Object>());//共同交易人
        }
		return result;
	}
	
	/**
	 * 根据案件id查询交易金额占比
	 * @return
	 */
	@RequestMapping(value = "/getMoneyForEC", method = RequestMethod.POST)
	@ResponseBody
	public Object findTMoneyForByCaseManagerId() {
		String caseManagerId = request.getSession().getAttribute("caseId") == null?"":request.getSession().getAttribute("caseId").toString();
		Map<String, Object> result = new HashMap<String, Object>();
		List<Map<String, Object>> moneyFor = dealFlowService.findTMoneyForByCaseManagerId(caseManagerId);
        if(moneyFor != null && moneyFor.size() > 0) {
        	if (moneyFor.size() > 10) {
        		List<Map<String, Object>> rows = moneyFor.subList(0, 10);
				result.put("rows", rows);//共同交易人
			}else {
				result.put("rows", moneyFor);//共同交易人
	        }
        }else {
        	result.put("rows", new ArrayList<Object>());//共同交易人
        }
		return result;
	}
	
	/**
	 * 账单概况ec详情
	 * @param model
	 * @param pagesupport
	 * @return
	 */
	@RequestMapping(value = "/getECDetails4AccountBodyInit", method = RequestMethod.GET)
	public Object getECDetails4AccountBodyInit(ModelMap model, String accountBody) {
		model.addAttribute("accountBody", accountBody);
		return "/bill/echartsDetailslist";
	}
	
	/**
	 * 账单概况eczero详情
	 * @param model
	 * @param pagesupport
	 * @return
	 */
	@RequestMapping(value = "/findEcDetails4ZeroInit", method = RequestMethod.GET)
	public Object findEcDetails4ZeroInit(ModelMap model, String accountBody) {
		model.addAttribute("accountBody", accountBody);
		return "/bill/echartsDetailslistZero";
	}
	
	/**
	 * 账单概况ec详情
	 * @param model
	 * @param pagesupport
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/getECDetails4AccountBody")
	public Object getECDetails4AccountBody(String sortName,String sortOrder,ModelMap model, PageSupport pagesupport
			,@Param("accountBody")String accountBody) {
		String caseId = request.getSession().getAttribute("caseId") == null?"":request.getSession().getAttribute("caseId").toString();
		Page<BillStatusDomain> page = dealFlowService.findEcDetailsHeadQuarter(sortName,sortOrder,caseId, accountBody, pagesupport.getPage());
		model.addAttribute("page", page);
		Map<String, Object> result = new HashMap<String,Object>();
		result.put("total", page.getTotalElements());
		result.put("rows", page.getContent());
		return result;
	}
	
	/**
	 * 账单概况ec金额占比详情
	 * @param model
	 * @param pagesupport
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/findEcDetails4Zero")
	public Object getEcDetails4Zero(String sortName,String sortOrder,ModelMap model, PageSupport pagesupport
			,@Param("accountBody")String accountBody) {
		String caseId = request.getSession().getAttribute("caseId") == null?"":request.getSession().getAttribute("caseId").toString();
		Page<DealFlow> page = dealFlowService.findEcDetails4Zero(sortName,sortOrder,caseId, accountBody, pagesupport.getPage());
		Map<String, Object> result = new HashMap<String,Object>();
		model.addAttribute("page", page);
		result.put("total", page.getTotalElements());
		result.put("rows", page.getContent());
		return result;
	}
	
	/**
	 * 账单概况列表查询
	 * @param sortName
	 * @param sortOrder
	 * @param model
	 * @param dealFlow
	 * @param pageNumber
	 * @param pageSize
	 * @return
	 */
    @ResponseBody
    @RequestMapping(value = "/billStatusList")
	public Object billStatusList(DealFlowVo dealFlow) {
		String caseId = request.getSession().getAttribute("caseId") == null?"":request.getSession().getAttribute("caseId").toString();
		dealFlow.setCasemanageId(caseId);
		return dealFlowService.findBillStatus4Page(dealFlow,dealFlow.getSort(),dealFlow.getOrder(), dealFlow.getPage(), dealFlow.getRows());
	}
	
	@RequestMapping(value = "/getInStreamAccountD3Init", method = RequestMethod.GET)
	public Object getInStreamAccountD3Init(ModelMap model) {
		return "/bill/billStatusD3";
	}

    /**
     *
     * @param response
     * @param dealFlow
     * @throws Exception
     */
    @RequestMapping(value = "/getInStreamAccountD3")
    @ResponseBody
    public Object getInStreamAccountD3(DealFlowDto dealFlowdto){
        String caseId = request.getSession().getAttribute("caseId") == null?"":request.getSession().getAttribute("caseId").toString();
        return dealFlowService.getInStreamAccountD3(caseId);
    }

    /**
     * 账单导出
     * @throws Exception 
     */
    @RequestMapping("/status/export")
    @ResponseBody
    public void exportFile(HttpServletResponse response, DealFlowVo dealFlow) throws Exception {

        // 生成导出excel名称
        Date date = new Date();
        DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String fileName = "账单概况" + dateFormat.format(date);

        //设置导出Excel标题
        String[] titles = {"交易主体", "交易主体账号", "交易主体卡号","交易地点","归属银行","交易总金额","交易总次数","交易余额","净流入额", "流入金额","流出金额","开始时间","结束时间"};

        //  String[] titles =new String[30];  不写死需要前台传fail文件
        //遍历导出Excel的内容
        String uuid = request.getSession().getAttribute("caseId") == null?"":request.getSession().getAttribute("caseId").toString();
        dealFlow.setCasemanageId(uuid);
        List<BillStatusDomain> list = new ArrayList<BillStatusDomain>();
        if(StringUtils.isNotEmpty(uuid)) {
        	list =  dealFlowService.findBillStatus(dealFlow,null,null);
        }
        List<Map<Integer, String>> lists = new ArrayList<Map<Integer, String>>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (BillStatusDomain df : list) {
            Map<Integer, String> map = new HashMap<Integer, String>();
            //交易主体
            map.put(0, df.getAccountBody()==null ? "" : df.getAccountBody());
            //交易主体账号
            map.put(1, df.getAccountBodyNumber()==null ? "" : df.getAccountBodyNumber().toString());
            //交易主体卡号
            map.put(2, df.getAccountBodyCard()==null ? "" : df.getAccountBodyCard().toString());
            //交易地点
            map.put(3, df.getAccountAddress()==null ? "" : df.getAccountAddress());
            //归属银行
            map.put(4, df.getAccountBodyBank()==null ? "" : df.getAccountBodyBank());
            //交易总金额
            map.put(5, df.getTotalMoney()==null ? "" : df.getTotalMoney().toString());
            //交易总次数
            map.put(6, df.getTotalCount()==null ? "0" : df.getTotalCount().toString());
            //交易余额
            map.put(7,df.getSurPlusMoney()==null ? "" : df.getSurPlusMoney().toString());
            //净流入额
            map.put(8, df.getTotalInMoney()==null ? "" : df.getTotalInMoney().toString());
            //流入金额
            map.put(9, df.getInMoney()==null ? "" : df.getInMoney().toString());
            //流出金额
            map.put(10, df.getOutMoney()==null ? "" : df.getOutMoney().toString());
            //开始时间
            if(df.getBeginDate()!=null) {
            	map.put(11, sdf.format(df.getBeginDate()));
            }else {
            	map.put(11, "");
            }
            //结束时间
            if(df.getEndDate()!=null) {
            	map.put(12, sdf.format(df.getEndDate()));
            }else {
            	map.put(12, "");
            }
            //把map集合添加到lists集合
            lists.add(map);
        }

        //插入导出日志
        dataOperationLogService.save(null, super.getLoginUser(), new DealFlow(), new DealFlow(), SystemFlag.ZD, ModuleFlag.BILLSTATUS, ActionType.EXPORT);
        // 把导出的内容写入到流里面
        byte[] content = ExcelUtil.writeExcel(titles, lists);
        InputStream is = new ByteArrayInputStream(content);

        // 设置response参数，可以打开下载页面
        response.reset();
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + new String((fileName + ".xls").getBytes(), "iso-8859-1"));
        ServletOutputStream out = response.getOutputStream();
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            bis = new BufferedInputStream(is);
            bos = new BufferedOutputStream(out);
            byte[] buff = new byte[2048];
            int bytesRead;
            while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                bos.write(buff, 0, bytesRead);
            }
        } catch (final IOException e) {
            throw e;
        } finally {
            if (bis != null) {
                bis.close();
            }
            if (bos != null) {
                bos.close();
            }
        }
    }
    @SuppressWarnings("rawtypes")
	class SortList implements Comparator {
		public int compare(Object o1, Object o2) {
			CommonStatistics w1 = (CommonStatistics) o1;
			CommonStatistics w2 = (CommonStatistics) o2;
			return w2.getOccurrences().compareTo(w1.getOccurrences());
		}
	}
    @RequestMapping(value = "/testD3Tree")
    @ResponseBody
    public Object testD3Tree(DealFlowDto dealFlowdto){
        Map<String, Object> result = new HashMap<String, Object>();
        HashMap<String, Object> node = new HashMap<>();
	    node.put("id",UUID.randomUUID().toString());
	    node.put("name","父节点");
	    List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
	    HashMap<String, Object> node1 = new HashMap<>();
	    node1.put("id",UUID.randomUUID().toString());
	    node1.put("name","子节点1");
	    node1.put("parentlinename","子节点1");
	    node1.put("float","left");
	    HashMap<String, Object> node2 = new HashMap<>();
	    node2.put("id",UUID.randomUUID().toString());
	    node2.put("name","子节点2");
//	    node2.put("float","left");
	    node2.put("parentlinename","子节点2");
	    list.add(node1);
	    list.add(node2);
	    list.add(node2);
	    list.add(node2);
	    list.add(node2);
	    list.add(node2);
	    list.add(node1);
	    list.add(node2);
	    list.add(node2);
	    list.add(node2);
	    list.add(node2);
	    list.add(node2);
	    list.add(node2);
	    list.add(node2);
	    list.add(node2);
	    list.add(node2);
	    list.add(node2);
	    list.add(node2);
	    list.add(node2);
	    list.add(node2);
	    list.add(node2);
	    list.add(node2);
	    node.put("children",list);
	    
	    result.put("nodes", node);
        return result;
    }
}
